package com.luozm.captcha;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Handler;
import java.util.prefs.Preferences;

/**
 * Created by luozhanming on 2018/1/17.
 */

public class Captcha extends DirectionalLayout {

    //控件成员
    private PictureVertifyView vertifyView;         //拼图块
    private TextSeekbar seekbar;                    //滑动条块
    private Component accessSuccess, accessFailed;       //验证成功/失败显示的视图
    private Text accessText, accessFailedText;  //验证成功/失败显示的文字
    private Image refreshView;                  //刷新按钮
    //控件属性
    private Element drawableId;          //验证图片资源id
    private Element progressDrawableId;  //滑动条背景id
    private Element thumbDrawableId;     //滑动条滑块id
    private int mMode;               //控件验证模式(有滑动条/无滑动条)
    private int maxFailedCount;      //最大失败次数
    private int failCount;           //已失败次数
    private int blockSize;           //拼图缺块大小

    //处理滑动条逻辑
    private boolean isResponse;
    private boolean isDown;

    private CaptchaListener mListener;

    /**
     * 带滑动条验证模式
     */
    public static final int MODE_BAR = 1;
    /**
     * 不带滑动条验证，手触模式
     */
    public static final int MODE_NONBAR = 2;


    public interface CaptchaListener {

        /**
         * Called when captcha access.
         *
         * @param time cost of access time
         * @return text to show,show default when return null
         */
        String onAccess(long time);

        /**
         * Called when captcha failed.
         *
         * @param failCount fail count
         * @return text to show,show default when return null
         */
        String onFailed(int failCount);

        /**
         * Called when captcha failed
         *
         * @return text to show,show default when return null
         */
        String onMaxFailed();

    }


    public Captcha(Context context) {
        super(context);
    }

    public Captcha(Context context, AttrSet attrs) {
        super(context, attrs);
        drawableId=Utils.getAttrSetElement(attrs,"src");
        progressDrawableId=Utils.getAttrSetElement(attrs,"progressbg");
        thumbDrawableId=Utils.getAttrSetElement(attrs,"thumbbg");
        blockSize=Utils.getAttrSetInt(attrs,"blockSize",50);
        maxFailedCount=Utils.getAttrSetInt(attrs,"max_fail_count",5);
        mMode=Utils.getAttrSetString(attrs,"mode","mode_bar").equals("mode_bar")? MODE_BAR : MODE_NONBAR;
        init();
    }


    private void init() {
        Component parentView = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_container, this, true);
        vertifyView = (PictureVertifyView) parentView.findComponentById(ResourceTable.Id_vertifyView);
        seekbar = (TextSeekbar) parentView.findComponentById(ResourceTable.Id_seekbar);
        accessSuccess = parentView.findComponentById(ResourceTable.Id_accessRight);
        accessFailed = parentView.findComponentById(ResourceTable.Id_accessFailed);
        accessText = (Text) parentView.findComponentById(ResourceTable.Id_accessText);
        accessFailedText = (Text) parentView.findComponentById(ResourceTable.Id_accessFailedText);
        refreshView = (Image) parentView.findComponentById(ResourceTable.Id_refresh);
        setMode(mMode);
        if (drawableId != null) {
            vertifyView.setImageElement(drawableId);
            vertifyView.invalidate();
        }
        setBlockSize(blockSize);
        vertifyView.callback(new PictureVertifyView.Callback() {
            @Override
            public void onSuccess(long time) {
                if (mListener != null) {
                    String s = mListener.onAccess(time);
                    if (s != null) {
                        accessText.setText(s);
                    } else {//默认文案
                        try {
                            String element = getResourceManager().getElement(ResourceTable.String_vertify_access).getString();
                            accessText.setText(String.format(element, time));
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (NotExistException e) {
                            e.printStackTrace();
                        } catch (WrongTypeException e) {
                            e.printStackTrace();
                        }
                    }
                }
                accessSuccess.setVisibility(VISIBLE);
                accessFailed.setVisibility(INVISIBLE);
            }

            @Override
            public void onFailed() {
                seekbar.setEnabled(false);
                vertifyView.setTouchEnable(false);
                failCount = failCount > maxFailedCount ? maxFailedCount : failCount + 1;
                accessFailed.setVisibility(VISIBLE);
                accessSuccess.setVisibility(HIDE);
                if (mListener != null) {
                    if (failCount == maxFailedCount) {
                        String s = mListener.onMaxFailed();
                        if (s != null) {
                            accessFailedText.setText(s);
                        } else {//默认文案
                            try {
                                String element = getResourceManager().getElement(ResourceTable.String_vertify_failed).getString();
                                accessFailedText.setText(String.format(element, maxFailedCount - failCount));
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (NotExistException e) {
                                e.printStackTrace();
                            } catch (WrongTypeException e) {
                                e.printStackTrace();
                            }
                        }
                    } else {
                        String s = mListener.onFailed(failCount);
                        if (s != null) {
                            accessFailedText.setText(s);
                        } else {//默认文案
                            try {
                                String element = getResourceManager().getElement(ResourceTable.String_vertify_failed).getString();
                                accessFailedText.setText(String.format(element, maxFailedCount - failCount));
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (NotExistException e) {
                                e.printStackTrace();
                            } catch (WrongTypeException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }

        });
        setSeekBarStyle(progressDrawableId, thumbDrawableId);
        //用于处理滑动条渐滑逻辑
        seekbar.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int progress, boolean b) {
                if (isDown) {  //手指按下
                    isDown = false;
                    if (progress > 10) { //按下位置不正确
                        isResponse = false;
                    } else {
                        isResponse = true;
                        accessFailed.setVisibility(HIDE);
                        vertifyView.down(0);
                    }
                }
                if (isResponse) {
                    vertifyView.move(progress);
                } else {
                    seekbar.setProgressValue(0);
                }
            }

            @Override
            public void onTouchStart(Slider slider) {
                isDown = true;
            }

            @Override
            public void onTouchEnd(Slider slider) {
                if (isResponse) {
                    vertifyView.loose();
                }
            }
        });
        refreshView.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component v) {
                startRefresh(v);
            }
        });
    }

    AnimatorProperty animatorProperty;

    private void startRefresh(Component v) {
        //点击刷新按钮，启动动画
        if (animatorProperty != null) {
            animatorProperty.start();
        } else {
            animatorProperty = v.createAnimatorProperty();
            animatorProperty.rotate(360).setDuration(500)
                    .setStateChangedListener(new Animator.StateChangedListener() {
                        @Override
                        public void onStart(Animator animator) {

                        }

                        @Override
                        public void onStop(Animator animator) {

                        }

                        @Override
                        public void onCancel(Animator animator) {

                        }

                        @Override
                        public void onEnd(Animator animator) {
                            reset(false);
                            animatorProperty.reset();
                        }

                        @Override
                        public void onPause(Animator animator) {

                        }

                        @Override
                        public void onResume(Animator animator) {

                        }
                    });
            animatorProperty.start();
        }

    }


    public void setCaptchaListener(CaptchaListener listener) {
        this.mListener = listener;
    }

    public void setCaptchaStrategy(CaptchaStrategy strategy) {
        if (strategy != null) {
            vertifyView.setCaptchaStrategy(strategy);
        }
    }

    public void setSeekBarStyle(Element progressDrawable, Element thumbDrawable) {
        seekbar.setBackground(progressDrawable);
        seekbar.setProgressElement(progressDrawable);
        seekbar.setThumbElement(thumbDrawable);
    }

    public void setSeekBarStyle(int progressDrawable, int thumbDrawable) {
        ShapeElement progressElement = new ShapeElement(getContext(), progressDrawable);
        ShapeElement thumbElement = new ShapeElement(getContext(), thumbDrawable);
        seekbar.setBackground(progressElement);
        seekbar.setProgressElement(progressElement);
        seekbar.setThumbElement(thumbElement);
    }

    /**
     * 设置滑块图片大小，单位px
     *
     * @param blockSize 大小
     */
    public void setBlockSize(int blockSize) {
        this.blockSize=blockSize;
        vertifyView.setBlockSize(blockSize);
    }

    public int getBlockSize() {
        return blockSize;
    }

    /**
     * 设置滑块验证模式
     *
     * @param mode  模式
     */
    public void setMode(int mode) {
        this.mMode = mode;
        vertifyView.setMode(mode);
        if (mMode == MODE_NONBAR) {
            seekbar.setVisibility(HIDE);
            vertifyView.setTouchEnable(true);
        } else {
            seekbar.setVisibility(VISIBLE);
            seekbar.setEnabled(true);
        }
        hideText();
    }

    public int getMode() {
        return this.mMode;
    }

    public void setMaxFailedCount(int count) {
        this.maxFailedCount = count;
    }

    public int getMaxFailedCount() {
        return this.maxFailedCount;
    }



    public void setBitmap(PixelMap bitmap) {

        vertifyView.setBitmap(bitmap);
        reset(false);
    }

    public void setBitmap(String imgurl) {
        TaskDispatcher refreshUITask = getContext().createParallelTaskDispatcher("", TaskPriority.DEFAULT);
        refreshUITask.syncDispatch(() -> {
            new BitmapLoaderTask(imgurl, new BitmapLoaderTask.Callback() {
                @Override
                public void result(PixelMap bitmap) {
                    setBitmap(bitmap);
                    bitmap.release();
                }
            });
        });
    }

    /**
     * 复位
     *
     * @param clearFailed 是否清除失败次数
     */
    public void reset(boolean clearFailed) {
        hideText();
        vertifyView.reset();
        if (clearFailed) {
            failCount = 0;
        }
        if (mMode == MODE_BAR) {
            seekbar.setEnabled(true);
            seekbar.setProgressValue(0);
        } else {
            vertifyView.setTouchEnable(true);
        }
    }

    /**
     * 隐藏成功失败文字显示
     */
    public void hideText() {
        accessFailed.setVisibility(HIDE);
        accessSuccess.setVisibility(HIDE);
    }



}
